package com.huyun.web.modules.newJdk8;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author huyunqiang
 * @date 2019/7/4 21:57
 */
public class StreamApi {
    public static void main(String[] args) {

        /**
         * .distinct()
         * .limit(2)
         */

        //初始化
        List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1);

        //遍历
        integerList.forEach( item ->{
        });

        // map映射配个元素对应的结果
        List<Integer> squaresList = integerList.stream().map(i -> i*i).distinct().limit(2).collect(Collectors.toList());
        System.out.println("map映射配个元素对应的结果"+squaresList);



//        //过滤，收集所有偶数
        List<Integer> collecgt = integerList.stream()
                .filter(item -> item %2 ==1).distinct().collect(Collectors.toList());


        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        List<String> filtered = strings.stream()
                .filter(string -> !string.isEmpty()).collect(Collectors.toList());

//        //计算总和
        int sum = integerList.stream()
              .mapToInt(Integer::intValue).sum();
        int sum1 = integerList.stream()
                .mapToInt(i->i).reduce(0,Integer :: sum); //带初始值

        System.out.println("总和"+sum1);

        OptionalInt reduce1 = integerList
                .stream()
                .mapToInt(Integer::intValue)
                .reduce(Integer::sum);//不带初始值

        System.out.println("计算总和：" + reduce1);

        Integer reduce2 = integerList
                .stream()
                .reduce(0, (a, b) -> a + b);

        System.out.println("计算总和：" + reduce2);

        //计算数量
        long count = integerList.stream().count();
        System.out.println("计算数量" + count);

        Optional<Integer> collect8 = integerList.stream().collect(Collectors.maxBy((x1, x2) -> x1 - x2));
        Optional<Integer> collect9 = integerList.stream().collect(Collectors.maxBy(Comparator.comparing(Integer::intValue)));
        Optional<Integer> collect10 = integerList.stream().collect(Collectors.minBy(Comparator.comparing(Integer::intValue)));
        if (collect8.isPresent()) System.out.println("求最大值:" + collect8.get());
        if (collect9.isPresent()) System.out.println("求最大值:" + collect9.get());
        if (collect10.isPresent()) System.out.println("求最小值:" + collect10.get());

//
//
//        //求平均值
//        Double collect11 = integerList.stream().collect(Collectors.averagingInt(Integer::intValue));
//        System.out.println("求平均值：" + collect11);
//
//
        //一次性得到元素个数、总和、均值、最大值、最小值
        IntSummaryStatistics collect12 = integerList.stream().collect(Collectors.summarizingInt(Integer::intValue));

        System.out.println("一次性得到元素个数、总和、均值、最大值、最小值:" + collect12);

        //分组
        Map<Integer, List<Integer>> collect15 = integerList.stream().collect(
                Collectors.groupingBy(Integer::intValue)

        );

        Map<Integer,List<Integer>> collec = integerList.stream().collect(Collectors.groupingBy(i -> i));
        System.out.println("分组：" + collect15);
        System.out.println("分组2：" + collec);

        Map<Integer, Long> collect14 = integerList.stream().collect(
                Collectors.groupingBy(Integer::intValue, Collectors.counting())
        );
        System.out.println("可以有多级分组：" + collect14);

        //分区可以看做是分组的一种特殊情况，在分区中key只有两种情况：true或false
        Map<Boolean, List<Integer>> collect16 = integerList.stream().collect(Collectors.partitioningBy(x -> x >= 7));

        System.out.println("分区可以看做是分组的一种特殊情况，在分区中key只有两种情况：true或false:" + collect16);
//
//        //去重
//        List<Integer> collect1 = integerList
//                .stream()
//                .distinct()
//                .collect(Collectors.toList());
//        System.out.println("去重：" + collect1);
//
//
//        //limit返回包含前n个元素的流
//        List<Integer> collect2 = integerList
//                .stream()
//                .filter(integer -> integer % 2 == 0).limit(2)
//                .collect(Collectors.toList());
//        System.out.println("limit：" + collect2);


        //排序,倒序排序
        List<Integer> collect3 = integerList.
                stream()
                .sorted((s1, s2) -> s2 - s1)
                .collect(Collectors.toList());
        System.out.println("排序：" + collect3);

        //跳过前n个元素
        List<Integer> collect4 = integerList
                .stream()
                .filter(integer -> integer % 2 == 1).skip(2)
                .collect(Collectors.toList());
        System.out.println("skip：" + collect4);


        String[] strs = {"java8", "is", "easy", "to", "use"};

        //字符串拼接
        String collect13 = Arrays.stream(strs).collect(Collectors.joining());

        System.out.println("字符串拼接:" + collect13);


//        List<String[]> collect5 = Arrays.stream(strs)
//                .map(s -> s.split(","))//将字符串映射成字符数组
//                .collect(Collectors.toList());
//        System.out.println("将字符串映射成字符数组：" + collect5);

        //flatMap是将一个流中的每个值都转成一个个流，然后再将这些流扁平化成为一个流
        List<String> collect7 = Arrays.stream(strs)
                .map(s -> s.split(""))//每个字符串映射成string[]
                .flatMap(Arrays::stream)//flatMap将由map映射得到的Stream<String[]>，转换成由各个字符串数组映射成的流Stream<String>
                .collect(Collectors.toList());
        System.out.println("flatMap是将一个流中的每个值都转成一个个流，然后再将这些流扁平化成为一个流:" + collect7);


        //多个字符串将各个字符拆开，去重
        List<String> collect6 = Arrays.stream(strs)
                .map(s -> s.split(""))
                .flatMap(Arrays::stream)
                .distinct()
                .collect(Collectors.toList());

        System.out.println("多个字符串将各个字符拆开，去重：" + collect6);


        //allMatch,检测是否全部都满足指定的参数行为
        boolean b = integerList.stream().allMatch(integer -> integer > 5);
        System.out.println("allMatch,检测是否全部都满足指定的参数行为：" + b);

        //anyMatch,检测是否存在一个或多个满足指定的参数行为
        boolean any = integerList.stream().anyMatch(integer -> integer > 5);
        System.out.println("anyMatch,检测是否存在一个或多个满足指定的参数行为：" + any);

        //nonMatch 检测是否不存在满足指定行为的元素
        boolean non = integerList.stream().noneMatch(integer -> integer > 5);
        System.out.println("nonMatch 检测是否不存在满足指定行为的元素：" + non);

        //用于返回满足条件的第一个元素

        Optional<Integer> first = integerList.stream().filter(integer -> integer > 6).findFirst();
        if (first.isPresent()) System.out.println("用于返回满足条件的第一个元素：" + first.get());

        //findAny相对于findFirst的区别在于，findAny不一定返回第一个，而是返回任意一个
        //实际上对于顺序流式处理而言，findFirst和findAny返回的结果是一样的，
        // 至于为什么会这样设计，当我们启用并行流式处理的时候，查找第一个元素往往会有很多限制，如果不是特别需求，
        // 在并行流式处理中使用findAny的性能要比findFirst好。
        Optional<Integer> any1 = integerList.stream().filter(integer -> integer > 1).distinct().findAny();
        if (first.isPresent()) System.out.println("findAny不一定返回第一个，而是返回任意一个：" + any1.get());
        // 启动并行流式处理虽然简单，只需要将stream()替换成parallelStream()即可，
        // 但既然是并行，就会涉及到多线程安全问题，所以在启用之前要先确认并行是否值得
        // （并行的效率不一定高于顺序执行），另外就是要保证线程安全。此两项无法保证，
        // 那么并行毫无意义，毕竟结果比速度更加重
        Optional<Integer> any2 = integerList.parallelStream().filter(integer -> integer > 1).distinct().findAny();
        if(any2.isPresent())System.out.println("并行流式处理:"+any2.get());


    }
}
